package blog.config;

import blog.service.impl.AdminServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AdminServiceImpl adminService;

    //请求授权验证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 访问权限
        http.authorizeRequests()
                .antMatchers("/admin/dist/**", "/admin/plugins/**").permitAll()
                .antMatchers("/admin/login").permitAll()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/*").permitAll();//意思是任何用户都要经过登录（身份验证）才能访问
        //在配置访问权限时要注意先后顺序，其中有一些包含关系

        // 登录配置
        http.formLogin()
                //登录页面由springsecurity自动生成，也可以自定义，但controller是由spring security自动生成的
                .usernameParameter("username")  //设置从页面接收的用户名参数名称
                .passwordParameter("password")  //设置从页面接收的密码参数名称
                .loginPage("/admin/login")          //设置登录页面
                .loginProcessingUrl("/login") // 登陆表单提交请求
                .defaultSuccessUrl("/admin/index"); // 设置默认登录成功后跳转的页面

        // 注销配置
        http.headers().contentTypeOptions().disable();
        http.headers().frameOptions().disable();    // 图片跨域
        http.csrf().disable();                      //关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
        http.logout().logoutSuccessUrl("/admin/login");        //注销后，回到登录页面
        http.logout().logoutUrl("/admin/logout")          //指定登出请求
                .deleteCookies("JSESSIONID");       //删除 session 存储在本地的 cookie

        // 记住我配置
        http.rememberMe().rememberMeParameter("remember");
    }

    // 用户授权验证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(adminService).passwordEncoder(passwordEncoder());
    }
    //在 userDetailsService 中传入继承 UserDetailsService 类的子类也就是在 serviceImpl 中的 UserServiceImpl ，具体的功能实现在其中
    // ，后面一般接上密码加密的方式，不然会报异常

    // 密码加密方式
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}